#include "bsp/bsp.h"
#include "gpio.h"
#include "version.h"
#include "stm32g4xx_ll_rcc.h" // IWYU pragma: export
#include "stm32g4xx_ll_pwr.h" // IWYU pragma: export
#include "stm32g4xx_ll_system.h" // IWYU pragma: export
#include "stm32g4xx_ll_utils.h" // IWYU pragma: export
#include "stm32g4xx_ll_bus.h"

void SystemClock_Config(void)
{
  LL_FLASH_SetLatency(LL_FLASH_LATENCY_4);
  while(LL_FLASH_GetLatency() != LL_FLASH_LATENCY_4)
  {
  }
  LL_PWR_EnableRange1BoostMode();
  LL_RCC_HSI_Enable();
   /* Wait till HSI is ready */
  while(LL_RCC_HSI_IsReady() != 1)
  {
  }

  LL_RCC_HSI_SetCalibTrimming(64);
  LL_RCC_HSI48_Enable();
   /* Wait till HSI48 is ready */
  while(LL_RCC_HSI48_IsReady() != 1)
  {
  }

  LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSI, LL_RCC_PLLM_DIV_4, 85, LL_RCC_PLLR_DIV_2);
  LL_RCC_PLL_EnableDomain_SYS();
  LL_RCC_PLL_Enable();
   /* Wait till PLL is ready */
  while(LL_RCC_PLL_IsReady() != 1)
  {
  }

  LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL);
  LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_2);
   /* Wait till System clock is ready */
  while(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL)
  {
  }

  /* Insure 1us transition state at intermediate medium speed clock*/
  for (__IO uint32_t i = (170 >> 1); i !=0; i--);

  /* Set AHB prescaler*/
  LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1);
  LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1);
  LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_1);
  LL_SetSystemCoreClock(170000000);

   /* Update the time base */
  if (HAL_InitTick (TICK_INT_PRIORITY) != HAL_OK)
  {
    //Error_Handler();
  }
}


void HAL_MspInit(void)
{
	__HAL_RCC_SYSCFG_CLK_ENABLE();
  	__HAL_RCC_PWR_CLK_ENABLE();

  	HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
  	/* SysTick_IRQn interrupt configuration */
  	HAL_NVIC_SetPriority(SysTick_IRQn, SCHED_TIMER_IRQ_PRIORITY, 0);

	HAL_PWREx_DisableUCPDDeadBattery();
}

static IWDG_HandleTypeDef hiwdg;
void MX_IWDG_Init(void)
{
#if (CONFIG_DEBUG==0)
	//wdog clk is 32k, 2s timeout
  	hiwdg.Instance = IWDG;
 	hiwdg.Init.Prescaler = IWDG_PRESCALER_16;
  	hiwdg.Init.Reload = 4095;
	hiwdg.Init.Window = 4095;
	HAL_IWDG_Init(&hiwdg);
#endif
}

void wdog_reload(void) {
#if (CONFIG_DEBUG==0)
	HAL_IWDG_Refresh(&hiwdg);
#endif
}

u8 mcu_chip_id(u8 *buff)
{
	u32 values[] = { REG32(0x1FFF7590), REG32(0x1FFF7594), REG32(0x1FFF7598)};
	memcpy(buff, values, sizeof(values));
	return sizeof(values);
}

